'''
This file is part of Lampy.

Lampy is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Lampy is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Lampy.  If not, see <http://www.gnu.org/licenses/>.

Copyright 2011 Kevin Han
'''

"""Old bits and pieces of failed attempts."""
##def getNames(node, inFuncs):
##    """
##    Return a set of names contained in node.
##    
##    If inFuncs, includes those in function bodies and parameters.
##
##    >>> getNames(['a'], False)
##    set(['a'])
##    >>> getNames([['/abc', ['/x', 'xbd']]], False)
##    set([])
##    >>> list(sorted(getNames([['/abc', ['/x', 'xbd']]], True)))
##    ['a', 'b', 'c', 'd', 'x']
##    """
##    if isName(node):
##        return set(node)
##    elif isFunc(node):
##        if not inFuncs:
##            return ''
##
##        params, body = splitFunc(node)
##        return set(params) | getNames(body, inFuncs)
##
##    return reduce(
##            set.union,
##            (getNames(innerNode, inFuncs) for innerNode in node),
##            set()
##            )

##def reduceFunc(func, args):
##    params, body = splitFunc(func)
##
##    argNames = getNames(args, True)
##    print argNames
##    nameToNew = getNameToNew(body, argNames)
##    print nameToNew
##
##    newBody = substitute(body, nameToNew)
##    print newBody
##    newParams = ''.join(substitute(list(params), nameToNew))
##    print newParams
##
##    paramToArg = dict(zip(newParams, args))
##    newBody = substitute(newBody, paramToArg)
##
##    extraParams = params[len(args):]
##    if extraParams:
##        return makeFunc(extraParams, newBody)
##    else:
##        return newBody
##
##def reduceOnce(parts, args={}, outerArgs={}):
##    """
##    Perform one round of reduction on parts.
##    
##    args is a mapping of parameters to args, outerArgs is a secondary mapping
##    for arguments bound outside the immediate function.
##    """
##    i = 0
##    newParts = []
##    while i < len(parts):
##        part = parts[i]
##        if isFunc(part):
##            # perform argument substitution into the function
##            params, body = splitFunc(part)
##
##            # get the new args
##            newArgs = parts[i + 1:i + 1 + len(params)]
##            # reduce all compound parts
##            for i, newArg in enumerate(newArgs):
##                if isCompound(newArg):
##                    newArgs[i] = reduceOnce(newArg, args, outerArgs)
####                newArgs[i] = rename(newArg, params)
##            newArgs = dict(zip(params, newArgs))
##
##            print 'new args', newArgs
##            
##            # store any extra parameters
##            extraParams = params[len(newArgs):]
##
##            # current args are added to the outer args
##            newOuterArgs = dict(outerArgs)
##            newOuterArgs.update(args)
##
##            # evaluate the body
##            newBody = reduceOnce(body, newArgs, newOuterArgs)
##
##            if extraParams:
##                # extra parameters left, it's still a function
##                newParts.append(makeFunc(extraParams, newBody))
##            else:
##                # completely evaluated, just another expression now
##                newParts += newBody
##            # start evaluating from the end of the consumed arguments
##            i += len(params)
##        elif isCompound(part):
##            newParts.append(reduceOnce(part, args, outerArgs))
##        elif part in args:
##            newParts.append(args[part])
##        elif part in outerArgs:
##            newParts.append(outerArgs[part])
##        else:
##            newParts.append(part)
##        i += 1
##    
##    return newParts
##
##def reduceExpr(parts):
##    """Reduce a parse tree as much as possible."""
##    while True:
##        newParts = reduceOnce(parts)
##        if newParts == parts:
##            return parts
##        parts = newParts

##def getNameToNew(func, names):
##    """
##    Return a mapping of names to new names that don't exist anywhere in body
##    save inner functions.
##    """
##    nameToNew = dict()
##    namesInFunc = getNames(body, False)
##    for name in names:
##        nameToNew[name] = getNewName(
##                name,
##                namesInFunc | set(nameToNew.values())
##                )
##    return nameToNew

##def convertFunc(func, args):
##    """
##    Perform alpha-conversion on func, changing parameter names and body to not
##    contain any names in argument list.
##
##    >>> convertFunc(['/ab', ['a', 'b']], ['a', 'b'])
##    None
##    >>> convertFunc(['/ab', ['a', ['/ab', ['a', 'b']]]], ['a', 'b'])
##    None
##    >>> convertFunc(['/ab', ['a', ['/cb', ['a', 'b', 'c']]]], ['b', 'a'])
##    >>> convertFunc(['/ab', ['a', ['/ab', ['a', 'b']]]], [['/a', ['a', 'b']]])
##    ['/ab', ['a', ['/ab', ['a', 'b']]]]
##    """
##    params, body = splitFunc(func)
##
##    argNames = getNames(args, False)
##
##    nameToNew = getNameToNew(body, argNames)
##
##    # substitute new names into parameters
##    newParams = ''.join(nameToNew[param] if param in nameToNew else param \
##            for param in params )
##
##    return makeFunc(newParams, newBody)

##def getRepr(node, i=None):
##    """
##    Return string representation of integer node, to avoid the recursion limit
##    when using parser.unparse().
##
##    It helps to pass the actual integer too so it doesn't have to call
##    fromNode().
##    """
##    if i is None:
##        i = fromNode(node)
##
##    f, x = splitFunc(node)[0]
##
##    params = '/%s%s.' % (f, x)
##    body = ((f + '(') * i)[:-1] + x + ')' * (i - 1)
##
##    return params + body
##

##if __name__ == '__main__':

##    parts = [['/xyz', ['x', 'y', 'z']], [['/y', ['y']], 'y', 'x']]
##    parts = [['/xyz', [['/x', ['x', 'y']], 'y', 'z']], [['/y', ['y']], 'y', 'x']]
##
##    f = ['/xyz', [['/x', ['x', 'y']], 'y', 'z', 'x']]
##    print 'orig', f, ['y', 'x']
##    print reduceFunc(f, ['y', 'x'])
